package com.dev.mybatisplus.config;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;

import java.util.Map;
import java.util.function.Consumer;

/**
 * @Classname CodeGenerator
 * @Description TODO
 * @Date 2022/7/16 9:44
 * @Author niu hao
 */
public class CodeGenerator {
    private static final String USER_DIR = System.getProperty("user.dir");
    private static final String BASE_PROJECT_NAME = "\\springboot-mybatisPlus3.5";
    private static final String BASE_DIR_NAME = "\\com\\dev\\mybatisplus";
    private static final String BASE_DIR_PATH = BASE_PROJECT_NAME + "\\src\\main\\java";
    private static final String BASE_ENTITY_PATH = BASE_DIR_PATH + BASE_DIR_NAME + "\\entity";
    private static final String BASE_SERVICE_PATH = BASE_DIR_PATH + BASE_DIR_NAME + "\\service";
    private static final String BASE_SERVICE_IMPL_PATH = BASE_SERVICE_PATH + "\\impl";
    private static final String BASE_MAPPER_PATH = BASE_DIR_PATH + BASE_DIR_NAME + "\\mapper";
    private static final String BASE_MAPPER_XML_PATH = BASE_MAPPER_PATH + "\\xml";
    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private static final String DATE_PATTERN = "yyyy-MM-dd";
    private static final String AUTHOR = "admin";

    /**
     * 数据源配置
     */
    public static DataSourceConfig.Builder getDataSourceConfig() {
        return new DataSourceConfig.Builder("jdbc:mysql://localhost:3306/mp", "root", "yizheng")
                //数据库查询
                .dbQuery(new MySqlQuery())
                //数据库 schema(部分数据库适用)
                //.schema("mybatis-plus")
                //数据库类型转换器
                .typeConvert(new MySqlTypeConvert())
                //数据库关键字处理器
                .keyWordsHandler(new MySqlKeyWordsHandler());
    }

    /**
     * 全局配置
     */
    public static Consumer<GlobalConfig.Builder> getGlobalConfig() {
        return builder -> builder
                //覆盖已生成文件
                //.fileOverride()
                //指定输出目录 默认值: windows:D:// linux or mac : /tmp
                .outputDir(USER_DIR + BASE_DIR_PATH)
                //作者名
                .author(AUTHOR)
                //开启 swagger 模式
                .enableSwagger()
                //时间策略 默认值: DateType.TIME_PACK
                .dateType(DateType.TIME_PACK)
                //注释日期
                .commentDate(DATE_PATTERN);
    }

    /**
     * 包配置
     */
    public static Consumer<PackageConfig.Builder> getPackageConfig() {
        return builder -> builder
                .parent("com.dev.mybatisplus")
                .entity("entity")
                .service("service")
                .serviceImpl("service.impl")
                .mapper("mapper")
                //.xml("mapper.xml")
                .controller("controller")
                .other("other")
                .pathInfo(Map.of(OutputFile.entity, USER_DIR + BASE_ENTITY_PATH,
                        OutputFile.mapper, USER_DIR + BASE_MAPPER_PATH,
                        //OutputFile.mapperXml, USER_DIR + BASE_MAPPER_XML_PATH,
                        OutputFile.service, USER_DIR + BASE_SERVICE_PATH,
                        OutputFile.serviceImpl, USER_DIR + BASE_SERVICE_IMPL_PATH)
                );
    }

    /**
     * 模板配置
     */
    public static Consumer<TemplateConfig.Builder> getTemplateConfig() {
        return builder -> builder
                //禁用xml文件生成
                .disable(TemplateType.XML)
                .entity("/templateEngine/entity1.java.vm")
                //.mapperXml("/templateEngine/mapper.xml.vm")
                .controller("/templateEngine/controllerBase.java.vm");
    }

    public static Consumer<StrategyConfig.Builder> getStrategyConfig(String... tableNames) {
        return builder -> builder
                //增加表匹配
                .addInclude(tableNames)
                //策略配置
                .entityBuilder()
                .fileOverride()
                //开启 ActiveRecord 模型
                //.enableActiveRecord()
                //开启 lombok 模型
                .enableLombok()
                //开启生成实体时生成字段注解
                .enableTableFieldAnnotation()
                //格式化文件名称
                //.formatFileName("%sEntity")
                //全局主键类型
                .idType(IdType.AUTO)
                //数据库表映射到实体的命名策略
                .columnNaming(NamingStrategy.underline_to_camel)
                //添加表字段填充
                //.addTableFills(new Column("create_time", FieldFill.INSERT))
                //添加表字段填充
                //.addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
                //Controller策略配置
                .controllerBuilder()
                .fileOverride()
                //设置父类
                .superClass("com.dev.mybatisplus.controller.base.BaseController")
                //开启生成@RestController 控制器
                .enableRestStyle()
                //格式化文件名称
                .formatFileName("%sController")
                //开启驼峰转连字符
                .enableHyphenStyle()
                //Service 策略配置
                .serviceBuilder()
                .fileOverride()
                //格式化 service 接口文件名称
                .formatServiceFileName("%sService")
                //格式化 service 实现类文件名称
                .formatServiceImplFileName("%sImpl")
                //Mapper 策略配置
                .mapperBuilder()
                .fileOverride()
                //开启 @Mapper 注解
                .enableMapperAnnotation()
                //启用 BaseResultMap 生成
                //.enableBaseResultMap()
                //启用 BaseColumnList
                //.enableBaseColumnList()
                //格式化 xml 实现类文件名称
                //.formatXmlFileName("%sMapper")
                //格式化 mapper 文件名称
                .formatMapperFileName("%sMapper");
    }

    public static void main(String[] args) {
        FastAutoGenerator.create(getDataSourceConfig())
                .globalConfig(getGlobalConfig())
                .packageConfig(getPackageConfig())
                .templateConfig(getTemplateConfig())
                .strategyConfig(getStrategyConfig("test"))
                .execute();
    }
}
